from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])

# 获取当前脚本的绝对路径，并找到父目录
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
# 将父目录添加到 Python 模块搜索路径
sys.path.append(parent_dir)
# Import the backtrader platform
import backtrader as bt

# 如果K线收盘价出现三连跌，则买入
class TestStrategy(bt.Strategy): 
    def log(self, txt, dt=None): 
        # 记录策略的执行日志  
        dt = dt or self.datas[0].datetime.date(0) 
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self): 
        # 保存收盘价的引用  
        self.dataclose = self.datas[0].close

    def next(self):
        # 记录收盘价  
        self.log('Close, %.2f' % self.dataclose[0]) 
        # 今天的收盘价 < 昨天收盘价  
        if self.dataclose[0] < self.dataclose[-1]: 
            # 昨天收盘价 < 前天的收盘价  
            if self.dataclose[-1] < self.dataclose[-2]:
                # 买入  
                self.log('买入, %.2f' % self.dataclose[0])
                self.buy()   # 买入的价格？？买入的资金？？

"""
若干个买入操作被执行，所以余额在减少。 细心的朋友可能会问，买了多少？买的什么？订单怎么被执行的?
BackTrader框架替我们做了这些事： 如果没有指定的话， self.datas[0]即是标的物当前交易数据。 
交易数量 =仓位数量，默认值等于1，后面例子我们会修改此参数。  
订单被以”市价”成交了。 Broker（经纪人，之前提到过）使用了下一个交易日的开盘价，因为是broker在当前的交日易收盘后天提交的订单，
下一个交易日开盘价是他接触到的第一个价格。 这里没有为订单设置佣金费，后边会加上。  
"""


if __name__ == '__main__':
    # Create a cerebro entity
    cerebro = bt.Cerebro()

    # Add a strategy
    cerebro.addstrategy(TestStrategy)

    # Datas are in a subfolder of the samples. Need to find where the script is
    # because it could have been called from anywhere
    modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
    datapath = os.path.join(modpath, '../datas/orcl-1995-2014.txt')

    # Create a Data Feed
    data = bt.feeds.YahooFinanceCSVData(
        dataname=datapath,
        # Do not pass values before this date
        fromdate=datetime.datetime(2000, 1, 1),
        # Do not pass values before this date
        todate=datetime.datetime(2000, 12, 31),
        # Do not pass values after this date
        reverse=False)

    # Add the Data Feed to Cerebro
    cerebro.adddata(data)

    # Set our desired cash start
    cerebro.broker.setcash(100000.0)

    # Print out the starting conditions
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

    # Run over everything
    cerebro.run()

    # Print out the final result
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())